/*
 * File: ContactFileEncryptor.java
 * Written by Kyle McCready, Viet Le, and David Hudson
 * Started April 11, 2012
 * Stored at http://code.google.com/p/sa-con-man/ on Google code
 * 
 * This program was written as the final project for CSE489 - Zero Defect 
 * Software Design Spring 2012. It follows the specification submitted on 
 * April 11 2012, which can be viewed online at: http://goo.gl/MH0Ol
 * 
 * This file is the encryption portion of the application, which works 
 * in conjunction with the following files:
 * ContactManager.java
 * ContactXMLParser.java
 * ContactXMLWriter.java
 */
package contactmanager;

import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.util.*;

public class ContactFileEncryptor
{
    private String password;
    private String EncryptionMode;
    private byte[] salt;
    private int iterations;

    public ContactFileEncryptor(String _password)
    {
        password = _password;
        EncryptionMode = "PBEWithMD5AndDES";
    }

    public void Encrypt(byte[] plaintext, String outfilename)
    {
        try
        {
            FileOutputStream outfile = 
                new FileOutputStream(outfilename);
            ByteArrayInputStream bais =
                new ByteArrayInputStream(plaintext);
            
            PBEKeySpec keyspec = 
                new PBEKeySpec(password.toCharArray());
            SecretKeyFactory skf = 
                SecretKeyFactory.getInstance(EncryptionMode);
            SecretKey sk = skf.generateSecret(keyspec);
            
            byte[] salt = new byte[8];
            Random rand = new Random();
            rand.nextBytes(salt);
            iterations = 100;

            PBEParameterSpec paramspec =    
                new PBEParameterSpec(salt, iterations);
            Cipher cipher = Cipher.getInstance(EncryptionMode);
            cipher.init(Cipher.ENCRYPT_MODE, sk, paramspec);
            outfile.write(salt);

            byte[] input = new byte[64];
            int bytesRead;
            while ((bytesRead = bais.read(input)) != -1)
            {
                 byte[] ciphertext = cipher.update(input, 0, bytesRead);
                 if (ciphertext != null) 
                     outfile.write(ciphertext);
            }            

            byte[] ciphertext = cipher.doFinal();
            if (ciphertext != null)
                outfile.write(ciphertext);
            outfile.flush();
            outfile.close();
        }
        catch (Exception e)
        {
            System.err.println("Error while decrypting: " + e.getMessage());
            e.printStackTrace();
        }
    }
}
